package main

import (
	"admin-nexus-backend/config"
	"admin-nexus-backend/internal/router"
	"admin-nexus-backend/pkg/database"
	"admin-nexus-backend/pkg/logger"
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gin-gonic/gin"
)

// @title 后台管理系统 API
// @version 1.0
// @description 后台管理系统后端 API 文档
// @termsOfService http://swagger.io/terms/

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @license.name MIT
// @license.url https://opensource.org/licenses/MIT

// @host localhost:8866
// @BasePath /api/v1

// @securityDefinitions.apikey BearerAuth
// @in header
// @name Authorization
// @description JWT Token，格式：Bearer {token}

func main() {
	// 1. 加载配置
	if err := config.LoadConfig(); err != nil {
		log.Fatalf("加载配置失败: %v", err)
	}

	// 2. 初始化日志
	if err := logger.InitLogger(); err != nil {
		log.Fatalf("初始化日志失败: %v", err)
	}
	defer logger.Sync()

	logger.Info("应用启动中...")

	// 3. 初始化数据库 - 开发环境下，如果连接失败，打印警告但继续运行
	if err := database.InitMySQL(); err != nil {
		logger.Info("警告: 初始化 MySQL 失败: " + err.Error() + "，继续运行...")
		// 使用内存数据库或模拟数据进行开发测试
	} else {
		logger.Info("MySQL 连接成功")

		// 5. 自动迁移数据库 - 可选，失败时继续运行
		if err := database.AutoMigrate(); err != nil {
			logger.Info("警告: 数据库迁移失败: " + err.Error() + "，继续运行...")
		} else {
			logger.Info("数据库迁移成功")
		}
	}

	// 4. 初始化 Redis - 可选，失败时继续运行（即使MySQL初始化失败也尝试初始化Redis）
	if err := database.InitRedis(); err != nil {
		logger.Info("警告: 初始化 Redis 失败: " + err.Error() + "，继续运行...")
	} else {
		logger.Info("Redis 连接成功")
	}

	// 6. 初始化验证码
	database.InitCaptcha()
	logger.Info("验证码服务初始化成功")

	// 7. 设置 Gin 模式
	gin.SetMode(config.GlobalConfig.App.Mode)

	// 8. 初始化路由（传入Redis实例）
	r := router.InitRouter(database.GetDB())

	// 9. 构建服务器地址
	addr := fmt.Sprintf("%s:%d", config.GlobalConfig.App.Host, config.GlobalConfig.App.Port)

	// 10. 创建 HTTP 服务器
	srv := &http.Server{
		Addr:    addr,
		Handler: r,
	}

	// 11. 启动服务器（优雅关闭）
	go func() {
		logger.Info(fmt.Sprintf("服务器启动成功，监听地址: %s", addr))
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			logger.Fatal("服务器启动失败: " + err.Error())
		}
	}()

	// 12. 等待中断信号以优雅关闭服务器
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	logger.Info("正在关闭服务器...")

	// 13. 设置 5 秒的超时时间
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := srv.Shutdown(ctx); err != nil {
		logger.Fatal("服务器关闭异常: " + err.Error())
	}

	logger.Info("服务器已关闭")
}
